package org.jzoie.sequece;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.search.DefaultSimilarity;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.util.Version;
import org.jzoie.ZoieDataInterpreter;
import org.jzoie.ZoieDocument;
import org.jzoie.ZoieQuery;
import org.jzoie.util.MemoryMap;

import proj.zoie.api.ZoieException;
import proj.zoie.api.ZoieIndexReader;
import proj.zoie.api.DataConsumer.DataEvent;
import proj.zoie.api.indexing.ZoieIndexableInterpreter;
import proj.zoie.impl.indexing.DefaultIndexReaderDecorator;
import proj.zoie.impl.indexing.ZoieConfig;
import proj.zoie.impl.indexing.ZoieSystem;

public class Sequeces 
{
	private static Map<String, Sequece> map=new HashMap<String, Sequece>();
	private static Analyzer analyzer=null;
	public static synchronized Sequece getSequece(Class cls)
	{
		Sequece sequece=map.get(cls.getName());
		if (sequece == null)
		{
			//????
			ZoieQuery<Sequece> zoieQuery=new ZoieQuery<Sequece>(Sequece.class);
			List<Sequece> list=null;
			try {
				list=zoieQuery.query("className", cls.getName(), false, 0, 1, null,null);
			} catch (Exception e) {
				//e.printStackTrace();
			}
			System.out.println("list="+list);
			if ((list==null)||(list.size()==0))
			{
				sequece=new Sequece();
				sequece.setClassName(cls.getName());
				sequece.setCount(0);
				List<Sequece> tempList=null;
				try {
					tempList=zoieQuery.query("className","*", false, 0, 1000, null,null);
				} catch (Exception e) {
					//e.printStackTrace();
					tempList=new ArrayList<Sequece>();
				}
				add(sequece, tempList.size());
			} else
			{
				sequece=list.get(0);
			}
			map.put(cls.getName(),sequece);
		}
		return sequece;
	}
	public static synchronized void update(Sequece sequece)
	{
		ZoieDocument<Sequece> zoieDocument=new ZoieDocument<Sequece>(Sequece.class);
		zoieDocument.update("className", sequece.getClassName(),sequece);
	}
	private static synchronized void add(Sequece sequece,long version)
	{
		
		if (sequece==null) {
			return;
		}
	 	List<ZoieIndexReader<IndexReader>> zoieReaderList = null;
        MultiReader multiReader = null;
        IndexSearcher indexSearcher = null;
        ZoieSystem<IndexReader, Sequece> zoieSystem=null;
        try {
			//get zoie system
        	 System.out.println("Sequeces addDocuments start size="+1);
             File idxDir = new File(ZoieDocument.DIRPATH+"/"+sequece.getClass().getSimpleName());
             if (idxDir.exists()==false) {
				idxDir.mkdirs();
			}
             // MyZoieDataInterpreter
             ZoieIndexableInterpreter<Sequece> interpreter = new ZoieDataInterpreter<Sequece>();
             //default
             DefaultIndexReaderDecorator decorator = new DefaultIndexReaderDecorator();
             
             ZoieConfig zoieConfig = new ZoieConfig();
             zoieConfig.setBatchDelay(1000);
             zoieConfig.setBatchSize(50000);
             zoieConfig.setAnalyzer(getAnalyzer());//
             zoieConfig.setSimilarity(new DefaultSimilarity());
             zoieConfig.setRtIndexing(true);
             zoieSystem = new ZoieSystem(idxDir, interpreter, decorator, zoieConfig);
             zoieSystem.start();
             
            long batchVersion = 0;
            ArrayList<DataEvent<Sequece>> eventList = new ArrayList<DataEvent<Sequece>>();
     		
     		batchVersion=version;
     		MemoryMap.set(sequece.toString(),batchVersion);
	     	DataEvent<Sequece> dataEvent=new DataEvent<Sequece>(sequece,batchVersion+"");
	     	eventList.add(dataEvent);
			
     		try {
     			zoieSystem.consume(eventList);
     			 zoieSystem.getAdminMBean().flushToMemoryIndex();
     			 zoieSystem.getAdminMBean().flushToDiskIndex();
     		} catch (ZoieException e) {
     			e.printStackTrace();
     		}
        	
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
            try {
                if (null != indexSearcher) 
                {
                    indexSearcher.close();
                    indexSearcher = null;
                }
                if (null != multiReader) 
                {
                    multiReader.close();
                    multiReader = null;
                }
                if (null != zoieReaderList && !zoieReaderList.isEmpty()) 
                {
                   zoieSystem.returnIndexReaders(zoieReaderList);
                   zoieReaderList = null;
                }
                if (zoieSystem !=null)
                {
                	zoieSystem.shutdown();
                	zoieSystem.stop();
				}
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
		
	}
	public static Analyzer getAnalyzer() {
		if (analyzer==null) {
			analyzer=new WhitespaceAnalyzer(Version.LUCENE_35);
		}
		return analyzer;
	}
}
